package annotation;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cglib.beans.BeanMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.common.collect.Maps;

import proxy.IRequestProxy;

/**
 * 执行代理方法
 *
 * @author wxf
 */
public class ProxyMethod {
	private Method method;
	private IRequestProxy iRequestProxy;
	private Logger logger = LoggerFactory.getLogger(ProxyMethod.class);

	public ProxyMethod(Method method, IRequestProxy iRequestProxy) {
		this.method = method;
		this.iRequestProxy = iRequestProxy;
		logger.debug("create ProxyMethod " + method);
	}

	public Object getProxy(Object[] args, String name) {
		Map<Object, Object> map = new HashMap<>();
		Map<Object, Object> urlMap = new HashMap<>();
		String url = "http://" + name + getUrl(method, urlMap, map, args);
		Type type = method.getAnnotatedReturnType().getType();
		String requestMethod = method.getAnnotation(RequestMapping.class).method()[0].name().toUpperCase();
		if (RequestMethod.GET.name().equals(requestMethod)) {
			return iRequestProxy.get(url, map, urlMap, type);
		} else {
			return iRequestProxy.post(url, map, urlMap, type);
		}

	}

	/**
	 * 获取请求url
	 */
	private String getUrl(Method method, Map<Object, Object> urlMap, Map<Object, Object> map, Object[] args) {
		// 获取方法注解
		RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
		if (requestMapping == null) {
			logger.error(method.getName() + "未添加注解 RequestMapping");
			throw new RuntimeException(method.getName() + "未添加注解 RequestMapping");
		}
		String requestUrl = requestMapping.value()[0];
		// 获取方法参数注解（接口方法参数中必须加注解RequestParam 为了获取方法参数名）
		Annotation[][] parameterAnnotations = method.getParameterAnnotations();
		int i = 0;
		for (Annotation[] parameterAnnotation : parameterAnnotations) {
			for (Annotation annotation : parameterAnnotation) {
				if (annotation instanceof RequestParam) {
					RequestParam param = (RequestParam) annotation;
					Object o = args[i++];
					// restFull api处理
					if (requestUrl.contains("{" + param.value() + "}")) {
						urlMap.put(param.value(), o);
						requestUrl = requestUrl.replace("{" + param.value() + "}", o + "");
					} else {
						if (isBaseType(o)) {
							map.put(param.value(), o);
						} else {
							map.putAll(object2Map(o));
						}
					}
				}
			}
		}
		return requestUrl;
	}

	/**
	 * 判断是不是基本类型
	 */
	private boolean isBaseType(Object object) {
		return object instanceof Integer || object instanceof Double || object instanceof Long
				|| object instanceof String || object instanceof Date;
	}

	/**
	 * 将对象装换为map
	 *
	 * @param object
	 * @return
	 */
	private Map<Object, Object> object2Map(Object object) {
		Map<Object, Object> map = Maps.newHashMap();
		if (object != null) {
			BeanMap beanMap = BeanMap.create(object);
			for (Object key : beanMap.keySet()) {
				map.put(key + "", beanMap.get(key));
			}
		}
		return map;
	}
}
